import config from '@/config/index.js'
import Login from '@/controller/Login'
import WxPay from '@/controller/WxPay'

export default {
  computed: {
    navBarHeight() {
      return this.$store.state.NavBar.navBarHeight
    }
  },
  onShow() {
    this.$eventHub.$on('login', data => {
      if (this.handleInit) {
        console.log('login handleInit ...')
        this.handleInit()
      }
    })
  },
  methods: {
    // 针对接口请求的错误处理
    errMsg(err, msg) {
      if (!msg) return
      if (!this.$format(err, 'msg')) {
        this.$msg('text', msg || '请求异常')
      }
    },
    /**
     * 获取最基础的请求参数
     * 可传参数 ['token', 'selectuniacid', 'usertoken']
     * 返回结果 { token: 'xx', selectuniacid: 'xx', usertoken: 'xx' }
     */
    getBase(returnKey = ['token', 'selectuniacid']) {
      const param = {}
      const rules = [] // 规则

      const loginInfo = this.$store.getters.loginInfo
      if (this.$isEmpty(loginInfo)) return this.$msg('text', '暂未获取到 loginInfo')

      if (returnKey.includes('token')) {
        param.token = loginInfo.token
        rules.push({ name: 'token', rule: ['required'], msg: ['小程序token字段为空'] })
      }

      if (returnKey.includes('selectuniacid')) {
        const selectBusiness = this.$store.getters.selectBusiness

        // 如果用户主动切换了商家，需要使用用户切换的商家id进行请求。 而不是直接使用后台登录返回的默认 selectuniacid 商家
        param.selectuniacid = this.$format(selectBusiness, 'selectuniacid', loginInfo.selectuniacid)
        rules.push({ name: 'selectuniacid', rule: ['required'], msg: ['登录的商家id字段为空'] })
      }

      if (returnKey.includes('usertoken')) {
        param.usertoken = loginInfo.usertoken
        rules.push({ name: 'usertoken', rule: ['required'], msg: ['用户登录态字段为空'] })
      }

      if (returnKey.includes('ordernum')) {
        param.ordernum = loginInfo.ordernum
        rules.push({ name: 'ordernum', rule: ['required'], msg: ['ordernum 字段为空'] })
      }

      if (returnKey.includes('bid')) {
        param.bid = loginInfo.bid
        rules.push({ name: 'bid', rule: ['required'], msg: ['bid 字段为空'] })
      }

      if (returnKey.includes('roomid')) {
        param.roomid = loginInfo.roomid
        rules.push({ name: 'roomid', rule: ['required'], msg: ['roomid 字段为空'] })
      }

      const checkRes = this.$validation.validate(param, rules)
      if (!checkRes) return param
      this.$msg('text', checkRes)

      return false
    },

    /**
     * 小程序用户登录
     * 场景：首页
     * 调用状态：报错
     * 作用：返回 usertoken
     */
    login(sortcodeParam) {
      return new Promise(async (resolve, reject) => {
        try {
          const sortcode = sortcodeParam
          const selectBusiness = this.$store.getters.selectBusiness
          const selectuniacid = this.$format(selectBusiness, 'selectuniacid')

          const baseParam = { appid: config.appid }

          // 二维码扫描
          if (sortcode) {
            Object.assign(baseParam, { sortcode })
          } else {
            // 如果切换了商家, 不跟二维码参数一起传。因为可能两个是两个房台号，会冲突
            if (selectuniacid) {
              Object.assign(baseParam, { selectuniacid })
            }
          }

          const code = await Login.loginCode()
          const param = Object.assign(baseParam, { code })
          const rules = [{ name: 'code', rule: ['required'], msg: ['code 字段为空'] }]
          const checkRes = this.$validation.validate(param, rules)
          if (checkRes) {
            this.$msg('text', checkRes)
            return reject()
          }

          // param.selectuniacid = 45 // 测试
          console.param('小程序用户登录 参数', param)

          this.$api
            .login(param)
            .then(res => {
              console.res('小程序用户登录 返回', res)
              const loginInfo = this.$format(res, 'data')
              if (this.$isEmpty(loginInfo)) {
                reject(res)
                return this.$msg('text', this.$format(res, 'msg', '暂未获取到用户登录数据'))
              }

              this.$store.dispatch('Business/setLoginInfo', res.data)
              resolve(loginInfo)
            })
            .catch(err => {
              console.err('小程序用户登录 错误', err)
              this.errMsg(err, '用户登录请求失败')
              reject(err)
            })
        } catch (err) {
          console.err(err)
          this.$msg('text', '小程序登录失败')
          reject()
        }
      })
    },

    /**
     * 初始化登录信息
     * room、selectuniacid、 bid、 usertoken、token
     */
    async initLoginInfo() {
      try {
        const ifLoginInfo = this.$store.getters.loginInfo

        if (!this.$isEmpty(ifLoginInfo)) {
          return Promise.resolve(ifLoginInfo)
        }

        const loginInfo = await this.login()
        return Promise.resolve(loginInfo)
      } catch (err) {
        return Promise.reject(err)
      }
    },

    /**
     * 获取门店列表
     */
    getStoreList() {
      return new Promise((resolve, reject) => {
        const baseParam = this.getBase(['token', 'selectuniacid'])
        if (!baseParam) return reject()
        console.param('获取门店列表', baseParam)
        this.$api
          .getStore(baseParam)
          .then(res => {
            console.res('获取门店列表', res)
            const stores = this.$format(res, 'data')
            this.$store.dispatch('Business/setStores', stores)
            resolve(stores)
          })
          .catch(err => {
            console.err('获取门店列表', err)
            this.errMsg(err, '获取门店列表失败')
            reject(err)
          })
      })
    },

    /**
     * 获取充值套餐列表
     * 场景：首页
     */
    getRechargeCardList(checktype = '首页') {
      return new Promise((resolve, reject) => {
        const baseParam = this.getBase(['token', 'selectuniacid', 'usertoken'])
        if (!baseParam) return reject()

        const checktypeDict = { 首页: 1, 更多: 2 }
        const param = Object.assign(baseParam, { checktype: checktypeDict[checktype] })
        console.param('获取充值套餐列表', baseParam)
        this.$api
          .getRechargeCardList(param)
          .then(res => {
            console.res('获取充值套餐列表', res)
            resolve(res)
          })
          .catch(err => {
            console.err('获取充值套餐列表', err)
            this.errMsg(err, '获取充值套餐列表失败')
            reject(err)
          })
      })
    },

    /**
     * 获取会员资料信息
     * @returns 头像 余额 手机号码 会员卡到期时间等等
     */
    getMemberInfo() {
      return new Promise((resolve, reject) => {
        const baseParam = this.getBase(['token', 'selectuniacid', 'usertoken'])
        if (!baseParam) return reject()

        console.param('获取会员资料信息', baseParam)
        this.$api
          .getMemberInfo(baseParam)
          .then(res => {
            console.res('获取会员资料信息', res)
            resolve(res)
          })
          .catch(err => {
            console.err('获取会员资料信息', err)
            this.errMsg(err, '获取会员资料信息失败')
            reject(err)
          })
      })
    },

    /**
     * 获取套餐配送列表
     * 必填: 'token', 'selectuniacid':登录的商家id, 'bid': 门店id, 'roomid': 房台id , 'stypeid': 小类id
     * 场景：扫码点单内点击选规格  / 推荐套餐详情页点击选规格 （ bid使用套餐详情接口携带的， roomid 不用传 ）
     */
    getMealDetail(goodsid, bid) {
      return new Promise((resolve, reject) => {
        if (!goodsid) {
          this.$msg('text', '物品id为空')
          return reject()
        }

        let baseParam

        if (bid) {
          baseParam = this.getBase(['token', 'usertoken', 'selectuniacid'])
          Object.assign(baseParam, { roomid: '' })
        } else {
          baseParam = this.getBase(['token', 'usertoken', 'selectuniacid', 'bid', 'roomid'])
        }

        if (!baseParam) return reject()

        Object.assign(baseParam, bid ? { goodsid, bid } : { goodsid })
        console.param('获取套餐配送列表', baseParam)
        this.$api
          .getMealDetail(baseParam)
          .then(res => {
            console.res('获取套餐配送列表', res)
            const selectMealForm = this.$format(res, 'data')
            resolve(selectMealForm)
          })
          .catch(err => {
            console.err('获取套餐配送列表', err)
            this.errMsg(err, '获取套餐配送列表失败')
            reject(err)
          })
      })
    },

    // 获取会员权益汇总
    getMemberAccount() {
      return new Promise((resolve, reject) => {
        const baseParam = this.getBase(['token', 'usertoken', 'selectuniacid'])
        if (!baseParam) return reject()
        console.param('获取会员权益汇总', baseParam)
        this.$api
          .getMemberAccount(baseParam)
          .then(res => {
            console.res('获取会员权益汇总', res)
            resolve(this.$format(res, 'data'))
          })
          .catch(err => {
            console.err('getMemberAccount', err)
            this.errMsg(err, '获取会员权益汇总失败')
            reject(err)
          })
      })
    },

    /**
     * 查询消费详情
     */
    getConsumeDetail(bid) {
      if (!bid) return this.$msg('text', '暂未获取到门店')
      return new Promise((resolve, reject) => {
        const baseParam = this.getBase(['token', 'usertoken', 'selectuniacid', 'ordernum'])
        if (!baseParam) return reject()
        Object.assign(baseParam, { bid })
        console.param('查询消费详情', baseParam)
        this.$api
          .getConsumeDetail(baseParam)
          .then(res => {
            console.res('查询消费详情', res)
            resolve(this.$format(res, 'data'))
          })
          .catch(err => {
            console.err('查询消费详情', err)
            this.errMsg(err, '获取消费详情失败')
            reject(err)
          })
      })
    },

    /**
     * 前端每次调用 wx.login 调用此接口（首次登录除外）
     */
    wxLogin() {
      return new Promise(async (resolve, reject) => {
        try {
          const baseParam = this.getBase(['token', 'usertoken', 'selectuniacid'])
          if (!baseParam) return reject()
          const code = await Login.loginCode()
          if (!code) return reject()

          Object.assign(baseParam, { code })
          console.param('前端每次调用 wx.login 调用此接口（首次登录除外）', baseParam)
          this.$api
            .wxLogin(baseParam)
            .then(res => {
              console.res('前端每次调用 wx.login 调用此接口（首次登录除外）', res)
              resolve(res)
            })
            .catch(err => {
              console.err('前端每次调用 wx.login 调用此接口（首次登录除外）', err)
              this.errMsg(err, '请求微信登录失败')
              reject(err)
            })
        } catch (err) {
          reject(err)
        }
      })
    },

    // 获取消费详情
    finalGetConsumeDetail(res) {
      const bid = this.$format(res, 'bid')
      if (!bid) return this.$msg('text', '暂未获取到门店')
      this.getConsumeDetail(bid)
        .then(res => {
          console.res('获取消费详情', res)
          if (!res) return this.$msg('text', '暂未查询到消费详情')

          if (this.$refs.consumeDetailModal) {
            this.$refs.consumeDetailModal.open({ consume: res })
          } else {
            console.log('获取消费详情 >> 请现在页面中添加 modal-consume-detail 组件')
          }
        })
        .catch(err => {
          console.err('获取消费详情', err)
          this.errMsg(err, '获取消费详情失败')
        })
    },

    /**
     * 充值订单支付
     * 请求获取充值订单支付的参数
     * 接受一个对象
     * 1. { cardtype: 4, bid: xx } 表示自定义充值 , 不需要传 roomid
     * 2. { rechargemoney: Float, bid: xx, roomid: xx }  表示充值卡id充值
     */
    submitRecharge(options) {
      return new Promise((resolve, reject) => {
        const bid = this.$format(options, 'bid')
        if (!bid) return this.$msg('text', '门店id不存在')

        // 如果非自定义充值，需要传房台号
        const diyRecharge = 4
        let roomid
        if (options.cardtype !== diyRecharge) {
          roomid = this.$format(options, 'roomid')
          // if (!roomid) return this.$msg('text', '房台号不存在')
        }

        const baseParam = this.getBase(['token', 'usertoken', 'selectuniacid'])
        if (!baseParam) return reject()

        Object.assign(baseParam, options.cardtype === 4 ? { rechargemoney: Number(options.rechargeMoney), bid } : { rechargeid: options.id, bid, roomid })
        console.param('充值订单支付', baseParam)
        this.$api
          .rechargePay(baseParam)
          .then(async res => {
            console.res('充值订单支付', res)

            const data = this.$format(res, 'data')
            this.wxPay(data).then(wxPayRes => {
              resolve(wxPayRes)
              setTimeout(() => {
                this.$open('/recharge/recharge', 'rt')
              }, 1500)
            })
          })
          .catch(err => {
            console.err('充值订单支付', err)

            const errCode = 1
            if (err.code === errCode) {
              this.errMsg(err, '请求充值订单失败')
              return reject(err)
            }

            // "检测到您还未授权手机号喔~请授权后再操作！"
            const noPhoneAuth = 2
            if (err.code === noPhoneAuth) {
              this.errMsg(err, '检测到您还未授权手机号喔~请授权后再操作！')
              return reject(err)
            }

            this.errMsg(err, '充值订单支付失败')
            reject(err)
          })
      })
    },

    wxPay(data, ifMsgSuccess = true) {
      return new Promise((resolve, reject) => {
        if (!data) {
          this.$msg('text', '支付参数不全')
          return reject()
        }

        const wxPay = new WxPay()
        const format = this.$format
        const param = {
          timeStamp: format(data, 'sdk_timestamp'),
          nonceStr: format(data, 'sdk_noncestr'),
          package: format(data, 'sdk_package'),
          paySign: format(data, 'sdk_paysign'),
          signType: format(data, 'sdk_signtype')
        }

        wxPay
          .requestPayment(param)
          .then(res => {
            ifMsgSuccess && this.$msg('success', '支付成功')
            resolve(res)
          })
          .catch(err => {
            console.err('requestPayment', err)
            const msg = this.$format(err, 'errMsg')
            if (msg === 'requestPayment:fail cancel') return
            reject(err)
          })
      })
    },

    // 检测会员是否授权手机号
    checkTelPhone() {
      return new Promise((resolve, reject) => {
        const baseParam = this.getBase(['token', 'usertoken', 'selectuniacid'])
        if (!baseParam) return reject()
        this.$api
          .checkTelPhone(baseParam)
          .then(res => {
            console.res('检测会员是否授权手机号', res)
            resolve(res)
          })
          .catch(err => {
            console.err('检测会员是否授权手机号', err)
            reject(err)
          })
      })
    },

    /**
     * 获取微信授权信息
     * 应用场景
     */
    getUserProfile() {
      return new Promise((resolve, reject) => {
        uni.getUserProfile({
          desc: '授权小程序获取手机号', // 声明获取用户个人信息后的用途，后续会展示在弹窗中，请谨慎填写
          success: res => {
            console.res('getUserProfile', res)
            const encryptedData = this.$format(res, 'encryptedData')
            const iv = this.$format(res, 'iv')

            if (encryptedData && iv) {
              return resolve(this.getUserPhone(encryptedData, iv))
            }

            this.$msg('text', '获取用户授权信息失败请重试')
            reject(res)
          },
          fail: err => {
            console.err('getUserProfile', err)
            this.$msg('text', '获取用户授权信息失败请重试')
            reject(err)
          }
        })
      }, 2000)
    },

    // 用户授权获取手机号码
    async getUserPhone(param) {
      console.param('用户授权获取手机号码', param)

      // await this.wxLogin()
      const encryptedData = this.$format(param, 'encryptedData')
      const iv = this.$format(param, 'iv')

      return new Promise(async (resolve, reject) => {
        if (!encryptedData || !iv) {
          reject()
          return this.$msg('text', '用户信息不全')
        }

        const baseParam = this.getBase(['token', 'selectuniacid', 'usertoken'])
        if (!baseParam) return reject()
        Object.assign(baseParam, { encryptedData, iv })

        console.param('用户授权获取手机号码', baseParam)
        this.$api
          .getUserPhone(baseParam)
          .then(res => {
            console.res('用户授权获取手机号码', res)
            resolve(res)
          })
          .catch(err => {
            console.err('用户授权获取手机号码', err)
            this.errMsg(err, '用户绑定手机号码失败')
            reject(err)
          })
      })
    },

    // 获取底部菜单
    getBottomNav() {
      return new Promise((resolve, reject) => {
        const baseParam = this.getBase(['token', 'usertoken', 'selectuniacid'])
        if (!baseParam) return reject()

        const tabBar = [
          {
            pop_title: '首页', //菜单标题
            redirect_url: 'pages/index/index', //菜单跳转位置
            pop_img: 'http://tbcrm.fwhtz.net/images/38/2019/11/f2PoVYVROjVRVvr3VlB3rLhbVH4YRp.png', //选中
            unselectimg: 'http://tbcrm.fwhtz.net/images/38/2019/11/ahKFfRbI1Bwek11wFQKk4QAiQ12ilF.png' //未选中
          },
          {
            pop_title: '消费介绍',
            redirect_url: '',
            pop_img: 'http://tbcrm.fwhtz.net/images/38/2019/11/N6P7jH5Z4Kk7Ll8dJ6JEeLBzriHJpj.png',
            unselectimg: 'http://tbcrm.fwhtz.net/images/38/2019/11/zPqkpZQZ4zS88SsiroS88I88OIrz8Q.png'
          },
          {
            pop_title: '会员二维码',
            redirect_url: '',
            pop_img: 'http://tbcrm.fwhtz.net/images/38/2019/11/iDWcjw9rXQ53DJUtYyX3E9uQ5L5SXZ.png',
            unselectimg: 'http://tbcrm.fwhtz.net/images/38/2019/11/KhsZqD7Rz93RkSDU09u7r3q7UU3r0H.png'
          },
          {
            pop_title: '好店推荐',
            position: 9,
            pop_img: 'http://tbcrm.fwhtz.net/images/38/2019/11/gV1x2o4BD2IPvvgcVbrdBxR2N74P2V.png',
            unselectimg: 'http://tbcrm.fwhtz.net/images/38/2019/11/U4rWiiIvA0V22rZi0mOn0Ag48A4vZ4.png'
          },
          {
            pop_title: '我的',
            position: 9,
            pop_img: 'http://tbcrm.fwhtz.net/images/38/2019/11/OXx2OIBmJBY3qq47Fb24QyvX3iYY4J.png',
            unselectimg: 'http://tbcrm.fwhtz.net/images/38/2019/11/W5598N2m0MAy0MAm158MZaV7utw9QZ.png'
          }
        ]

        resolve(tabBar)
        return

        console.param('获取底部菜单', baseParam)
        this.$api
          .getBottomNav()
          .then(res => {
            console.res('获取底部菜单', res)
          })
          .catch(err => {
            console.err('获取底部菜单 err', err)
          })
      })
    }
  }
}
